home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-03 | 16.2 KB | 598 lines | [TEXT/MPS ] |
- //----------------------------------------------------------------------------------------
- // UTracker.cp
- // Copyright © 1985-96 by Apple Computer, Inc. All rights reserved.
- //----------------------------------------------------------------------------------------
-
- #ifndef __UTRACKER__
- #include "UTracker.h"
- #endif
-
- // MacApp
-
- // #ifndef __UAPPLEEVENTS__
- // #include "UAppleEvents.h"
- // #endif
-
- // #ifndef __UAPPLICATION__
- // #include "UApplication.h"
- // #endif
-
- // #ifndef __UCLIPBOARDMGR__
- // #include "UClipboardMgr.h"
- // #endif
-
- // #ifndef __UDEBUG__
- // #include "UDebug.h"
- // #endif
-
- // #ifndef __UDEPENDENCIES__
- // #include "UDependencies.h"
- // #endif
-
- #ifndef __UDISPATCHER__
- #include "UDispatcher.h"
- #endif
-
- // #ifndef __UDOCUMENT__
- // #include "UDocument.h"
- // #endif
-
- // #ifndef __UERRORMGR__
- // #include "UErrorMgr.h"
- // #endif
-
- #ifndef __UGEOMETRY__
- #include "UGeometry.h"
- #endif
-
- #ifndef __UMACAPPGLOBALS__
- #include "UMacAppGlobals.h"
- #endif
-
- #ifndef __UMACAPPUTILITIES__
- #include "UMacAppUtilities.h"
- #endif
-
- #ifndef __UMEMORY__
- #include "UMemory.h"
- #endif
-
- // #ifndef __USCRIPTING__
- // #include "UScripting.h"
- // #endif
-
- #ifndef __USCROLLER__
- #include "UScroller.h"
- #endif
-
- #ifndef __USEGMENTS__
- #include "USegments.h"
- #endif
-
- #ifndef __UVIEW__
- #include "UView.h"
- #endif
-
- #ifndef __UWINDOW__
- #include "UWindow.h"
- #endif
-
- // Toolbox
-
- #ifndef __LOWMEM__
- #include <LowMem.h>
- #endif
-
- #ifndef __OSEVENTS__
- #include <OSEvents.h>
- #endif
-
- // ANSI
-
- #ifndef __STDIO__
- #include <stdio.h>
- #endif
-
- #ifndef __STDLIB__
- #include <stdlib.h>
- #endif
-
- //========================================================================================
- // CLASS TTracker
- //========================================================================================
- #undef Inherited
- #define Inherited TCommand
-
- #pragma segment MACommandNonRes
- MA_DEFINE_CLASS_M1(TTracker, Inherited);
-
- //----------------------------------------------------------------------------------------
- // TTracker::TTracker: Empty constructor to satisfy the compiler.
- //----------------------------------------------------------------------------------------
- #pragma segment MACommandRes
-
- TTracker::TTracker()
- {
- fConstrainsMouse = FALSE;
- fInitialPt = gZeroVPt;
- fScroller = NULL;
- fTrackNonMovement = FALSE;
- fView = NULL;
- fViewConstrain = TRUE;
- fTrackPhase = trackBegin;
- fAnchorPoint = gZeroVPt;
- fPreviousPoint = gZeroVPt;
- fNextPoint = gZeroVPt;
- fLastAnchorPoint = gZeroVPt;
- fLastPreviousPoint = gZeroVPt;
- fLastNextPoint = gZeroVPt;
- fDeskTopTrackingPort = NULL;
- fHysteresis = gZeroPt;
- fMovedOnce = FALSE;
- } // TTracker::TTracker
-
- //----------------------------------------------------------------------------------------
- // TTracker destructor
- //----------------------------------------------------------------------------------------
- #pragma segment MADestructorRes
-
- TTracker::~TTracker()
- {
- }
-
- //----------------------------------------------------------------------------------------
- // TTracker::ITracker:
- //----------------------------------------------------------------------------------------
- #pragma segment MACommandRes
-
- void TTracker::ITracker(CommandNumber itsCommandNumber,
- TCommandHandler* itsContext,
- Boolean canUndo,
- Boolean causesChange,
- TObject* objectToNotify,
- TView* itsView,
- TScroller* itsScroller,
- const VPoint& itsMouse)
- {
- this->ICommand(itsCommandNumber, itsContext, canUndo, causesChange, objectToNotify);
- fView = itsView;
- fScroller = itsScroller;
- fInitialPt = itsMouse;
- } // TTracker::ITracker
-
- //----------------------------------------------------------------------------------------
- // TTracker::AutoScroll:
- //----------------------------------------------------------------------------------------
- #pragma segment MADoCommand
-
- void TTracker::AutoScroll(const VPoint& delta)
- {
- if (fScroller)
- fScroller->ScrollBy(delta, kRedraw);
- } // TTracker::AutoScroll
-
- //----------------------------------------------------------------------------------------
- // TTracker::IsDoneTracking:
- //----------------------------------------------------------------------------------------
- #pragma segment MADoCommand
-
- Boolean TTracker::IsDoneTracking()
- {
- if (fView)
- return fView->IsDoneTracking();
- else
- return !StillDown();
- } // TTracker::IsDoneTracking
-
- //----------------------------------------------------------------------------------------
- // TTracker::Process:
- //----------------------------------------------------------------------------------------
- #pragma segment MACommandRes
-
- void TTracker::Process() // OVERRIDE
- {
- #if qDebugMsg
- if (gIntenseDebugging && this)
- fprintf(stderr, "Tracking Command: %s\n", this->GetClassName());
- #endif
-
- #if qSegments
- if (gDispatcher->fEventLevel == 1) // Don't unload segs if in nested event handling
- UnloadAllSegments();
- #endif
-
- TTracker* finalCommand = gDispatcher->TrackMouse(fInitialPt, TEventHandler::gStdHysteresis, this);
-
- if (finalCommand)
- {
- TCommandHandler* handler = finalCommand->fContext;
- if (handler)
- handler->PerformCommand(finalCommand);
- }
- } // TTracker::Process
-
- //----------------------------------------------------------------------------------------
- // TTracker::TrackConstrain:
- //----------------------------------------------------------------------------------------
- #pragma segment MADoCommand
-
- void TTracker::TrackConstrain(TrackPhase aTrackPhase,
- const VPoint& anchorPoint,
- const VPoint& previousPoint,
- VPoint& nextPoint,
- Boolean mouseDidMove)
- {
- if (fView)
- fView->TrackConstrain(aTrackPhase, anchorPoint, previousPoint, nextPoint, mouseDidMove);
- } // TTracker::TrackConstrain
-
- //----------------------------------------------------------------------------------------
- // TTracker::TrackFeedback:
- //----------------------------------------------------------------------------------------
- #pragma segment MADoCommand
-
- void TTracker::TrackFeedback(TrackPhase aTrackPhase,
- const VPoint& anchorPoint,
- const VPoint& previousPoint,
- const VPoint& nextPoint,
- Boolean mouseDidMove,
- Boolean turnItOn)
- {
- if (fView)
- fView->TrackFeedback(aTrackPhase, anchorPoint, previousPoint, nextPoint, mouseDidMove, turnItOn);
- } // TTracker::TrackFeedback
-
- //----------------------------------------------------------------------------------------
- // TTracker::TrackMouse:
- //----------------------------------------------------------------------------------------
- #pragma segment MADoCommand
-
- TTracker* TTracker::TrackMouse(TrackPhase aTrackPhase,
- VPoint& anchorPoint,
- VPoint& previousPoint,
- VPoint& nextPoint,
- Boolean mouseDidMove)
- {
- if (fView)
- fView->TrackMouse(aTrackPhase, anchorPoint, previousPoint, nextPoint, mouseDidMove);
-
- if ((aTrackPhase == trackEnd) && ((fView == NULL) ||!(fView->ContainsMouse(nextPoint))))
- return NULL;
- else
- return this;
- } // TTracker::TrackMouse
-
-
-
- //----------------------------------------------------------------------------------------
- // TTracker::CleanUpFocus:
- //----------------------------------------------------------------------------------------
- #pragma segment MADoCommand
-
- void TTracker::CleanUpFocus()
- {
- if (fDeskTopTrackingPort)
- {
- SetPortWindowPort(gWorkPort);
-
- if (qNeedsColorQD || HasColorQD())
- CloseCPort((CGrafPtr) fDeskTopTrackingPort);
- else
- ClosePort(fDeskTopTrackingPort);
- fDeskTopTrackingPort = (GrafPtr) DisposeIfPtr((Ptr) fDeskTopTrackingPort);
- fDeskTopTrackingPort = NULL;
- }
- } // CleanUpFocus
-
- //----------------------------------------------------------------------------------------
- // TTracker::DoFocus:
- //----------------------------------------------------------------------------------------
- #pragma segment MADoCommand
-
- void TTracker::DoFocus()
- {
- if (fView)
- {
- if (fDeskTopTrackingPort)
- this->CleanUpFocus();
-
- if (!fView->Focus())
- {
- #if qDebug
- ProgramBreak("TApplication.TrackMouse: Unable to focus fView.");
- #endif
- }
- }
- else
- { // focus on the desktop
- if (!fDeskTopTrackingPort)
- {
- fDeskTopTrackingPort = (GrafPtr) NewPermPtr(sizeof(CGrafPort));
- if (qNeedsColorQD || HasColorQD())
- OpenCPort((CGrafPtr) fDeskTopTrackingPort);
- else
- OpenPort(fDeskTopTrackingPort);
- }
-
- CopyRgn(GetGrayRgn(), TWindow::GetVisRegion(fDeskTopTrackingPort));
- fDeskTopTrackingPort->portRect = (*TWindow::GetVisRegion(fDeskTopTrackingPort))->rgnBBox;
- gDispatcher->InvalidateFocus();
- SetPort(fDeskTopTrackingPort);
- }
- } // TTracker::DoFocus
-
- //----------------------------------------------------------------------------------------
- // TTracker::BecomeTracker:
- //----------------------------------------------------------------------------------------
- #pragma segment MADoCommand
-
- void TTracker::BecomeTracker(TTracker* oldTracker)
- {
- if (oldTracker)
- {
- fDeskTopTrackingPort = oldTracker->fDeskTopTrackingPort;
- fTrackPhase = oldTracker->fTrackPhase;
-
- fHysteresis = oldTracker->fHysteresis;
- fTrackPhase = oldTracker->fTrackPhase;
- fAnchorPoint = oldTracker->fAnchorPoint;
- fPreviousPoint = oldTracker->fPreviousPoint;
- fNextPoint = oldTracker->fNextPoint;
- fLastAnchorPoint = oldTracker->fLastAnchorPoint;
- fLastPreviousPoint = oldTracker->fLastPreviousPoint;
- fLastNextPoint = oldTracker->fLastNextPoint;
- }
-
- this->DoFocus();
- } // TTracker::BecomeTracker
-
- //----------------------------------------------------------------------------------------
- // TTracker::ConstrainOnce:
- //----------------------------------------------------------------------------------------
- #pragma segment MADoCommand
-
- void TTracker::ConstrainOnce(Boolean didMouseMove)
- {
- if (this->fViewConstrain && (fView))
- fNextPoint.ConstrainTo(fView->GetExtent());
-
- if (this->fConstrainsMouse)
- {
- VPoint nextPoint = fNextPoint;
- this->TrackConstrain(fTrackPhase, fAnchorPoint, fPreviousPoint, nextPoint, didMouseMove);
- fNextPoint = nextPoint;
- }
- } // TTracker::ConstrainOnce
-
- //----------------------------------------------------------------------------------------
- // TTracker::FeedbackOnce:
- //----------------------------------------------------------------------------------------
- #pragma segment MADoCommand
-
- void TTracker::FeedbackOnce(Boolean mouseDidMove,
- Boolean turnItOn)
- {
- PenNormal();
- PenMode(patXor);
-
- if (turnItOn)
- {
- this->TrackFeedback(fTrackPhase, fAnchorPoint, fPreviousPoint,
- fNextPoint, mouseDidMove, turnItOn);
- // save these to turn it off with
- if (mouseDidMove)
- {
- fLastAnchorPoint = fAnchorPoint;
- fLastPreviousPoint = fPreviousPoint;
- fLastNextPoint = fNextPoint;
- }
- }
- else
- this->TrackFeedback(fTrackPhase, fLastAnchorPoint, fLastPreviousPoint,
- fLastNextPoint, mouseDidMove, turnItOn);
- } // TTracker::FeedbackOnce
-
- //----------------------------------------------------------------------------------------
- // TTracker::TrackOnce:
- //----------------------------------------------------------------------------------------
- #pragma segment MADoCommand
-
- TTracker* TTracker::TrackOnce(Boolean didMouseMove)
- {
- TView* oldView = fView;
- VPoint anchorPoint = fAnchorPoint;
- VPoint previousPoint = fPreviousPoint;
- VPoint nextPoint = fNextPoint;
-
- TTracker * newTracker = this->TrackMouse(fTrackPhase, anchorPoint, previousPoint, nextPoint, didMouseMove);
-
- fAnchorPoint = anchorPoint;
- fPreviousPoint = previousPoint;
- fNextPoint = nextPoint;
-
- if (newTracker == this)
- {
- if (this->fView != oldView)
- this->BecomeTracker(this);
- }
- else
- {
- if (newTracker)
- newTracker->BecomeTracker(this);
- else
- this->CleanUpFocus();
-
- // free me if a new tracker was returned
- if (this->ShouldFreeOnCompletion())
- {
- // // be sure to clear reference
- // if (fContext && fContext->fLastCommand == this) {
- // fContext->fLastCommand = NULL;
- // }
- this->Free();
- }
- }
-
- return newTracker;
-
- } // TTracker::TrackOnce
-
- //----------------------------------------------------------------------------------------
- // TTracker::HandleTrackBegin:
- //----------------------------------------------------------------------------------------
- #pragma segment MADoCommand
-
- TTracker* TTracker::HandleTrackBegin(const VPoint& theMouse,
- CPoint hysteresis)
- {
- fTrackPhase = trackBegin;
-
- fMovedOnce = FALSE;
- fDeskTopTrackingPort = NULL;
- fAnchorPoint = theMouse;
- fPreviousPoint = theMouse;
- fNextPoint = theMouse;
- fHysteresis = hysteresis,
-
- this->BecomeTracker(NULL);
-
- this->ConstrainOnce(TRUE);
- // in case Constrain changed the fNextPoint… guarantee that all 3 are the same on trackBegin
- fAnchorPoint = fNextPoint;
- fPreviousPoint = fNextPoint;
-
- TTracker* theTracker = this->TrackOnce(TRUE);
- if (theTracker)
- {
- // in case TrackMouse changed the fNextPoint… guarantee that all 3 are the same on trackBegin
- theTracker->fAnchorPoint = theTracker->fNextPoint;
- theTracker->fPreviousPoint = theTracker->fNextPoint;
-
- theTracker->FeedbackOnce(TRUE, TRUE);
- }
-
- return theTracker;
- } // TTracker::HandleTrackBegin
-
- //----------------------------------------------------------------------------------------
- // TTracker::HandleTrackContinue:
- //----------------------------------------------------------------------------------------
- #pragma segment MADoCommand
-
- TTracker* TTracker::HandleTrackContinue()
- {
- fTrackPhase = trackContinue; // supply trackphase to all interested parties
-
- this->DoFocus();
-
- CPoint theQDMouse;
- GetMouse(theQDMouse);
- if (fView)
- fNextPoint = fView->QDToViewPt(theQDMouse);
- else
- fNextPoint = theQDMouse;
-
- if (!fMovedOnce)
- {
- this->ConstrainOnce(fPreviousPoint != fNextPoint); // ensure that we are
- // playing on a level
- // field.
- VPoint amtMoved = fNextPoint - fAnchorPoint;
- if ((abs((int)amtMoved.h) >= fHysteresis.h) || (abs((int)amtMoved.v) >= fHysteresis.v))
- fMovedOnce = TRUE;
- }
-
- VPoint delta = gZeroVPt;
- if (fMovedOnce || fTrackNonMovement)
- {
- if (fScroller && fView)
- {
- // convert fNextPoint to scroller coordinates
- VPoint mouseInScroller = fNextPoint;
- fView->LocalToWindow(mouseInScroller);
- fScroller->WindowToLocal(mouseInScroller);
-
- // AutoScroll if the CPoint is outside of the scroller's extent
- if (!fScroller->GetExtent().Contains(mouseInScroller))
- {
- fScroller->AutoScroll(mouseInScroller, delta);// Get the amount to autoscroll
- fNextPoint += delta;
- }
- }
-
- this->ConstrainOnce(fPreviousPoint != fNextPoint);
- }
-
- Boolean willScroll = delta != gZeroVPt;
- Boolean didMove = fPreviousPoint != fNextPoint;
-
- this->FeedbackOnce(didMove || willScroll, FALSE);
-
- if (willScroll)
- {
- this->AutoScroll(delta); // OK, now actually do the scrolling
- if (fView)
- fView->Update(); // Keep synchronized. ScrollDraw only
- // invalidated
- this->DoFocus(); // the focus changed
- }
-
- TTracker* theTracker = this->TrackOnce(didMove);
- if (theTracker)
- {
- theTracker->FeedbackOnce(didMove || willScroll, TRUE);
- theTracker->fPreviousPoint = theTracker->fNextPoint;
- }
-
- return theTracker;
- } // TTracker::HandleTrackContinue
-
- //----------------------------------------------------------------------------------------
- // TTracker::HandleTrackEnd:
- //----------------------------------------------------------------------------------------
- #pragma segment MADoCommand
-
- TTracker* TTracker::HandleTrackEnd()
- {
- fTrackPhase = trackEnd; // supply trackphase to all interested parties
-
- this->DoFocus();
-
- EventRecord peekEvent;
-
- if (!fMovedOnce)
- fNextPoint = fPreviousPoint; // normally same as original mouse down;
- // we don't use fAnchorPoint in case
- // someone has changed that -- it is more
- // likely that an app would change
- // fAnchorPoint than fPreviousPoint
-
- else if (OSEventAvail(mUpMask + mDownMask, &peekEvent))
- {
- CPoint theQDMouse = peekEvent.where;
- if (fView)
- {
- GlobalToLocal(theQDMouse);
- fNextPoint = fView->QDToViewPt(theQDMouse);
- }
- else
- fNextPoint = theQDMouse;
- this->ConstrainOnce(TRUE);
- }
- // else we use the last known mouse position
-
- this->FeedbackOnce(TRUE, FALSE);
- TTracker* theTracker = this->TrackOnce(TRUE);
-
- if (theTracker)
- theTracker->CleanUpFocus();
-
- return theTracker;
- } // TTracker::HandleTrackEnd
-
-
- //----------------------------------------------------------------------------------------
- // End of UTracker.cp
-
- #pragma segment Inline
-